package com.cn.system.common.util;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * @Company <Jinher Technology Development Company LTD.>
 * @Project <Jinher Collaboration Suite>
 * @version <1.0>
 * @Author  <yangzq>
 * @Date    <Jun 4, 2009>
 *   
 * 提供高精度的运算支持.
 * 所以函数以double为参数类型，兼容int与float.
 */
public class NumberUtils {

	private NumberUtils() {

	}

	/**
	 * 精确的加法运算.
	 */
	public static double add(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.add(b2).doubleValue();
	}
	
	/**
	 * 
	 * 精确的减法运算.
	 * 
	 * @param v1 被减数

	 * @param v2 减数
	 */
	public static double subtract(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}
	
	/**
	 * 提供精确的乘法运算.
	 */
	public static double multiply(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.multiply(b2).doubleValue();
	}
	
	/**
	 * 提供精确的乘法运算，并对运算结果截位.
	 * 
	 * @param scale 运算结果小数后精确的位数
	 */
	public static double multiply(double v1, double v2,int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.multiply(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	}


	/**
	 * 提供（相对）精确的除法运算.
	 * 
	 * @see #divide(double, double, int)
	 */
	public static double divide(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.divide(b2).doubleValue();
	}

	/**
	 * 提供（相对）精确的除法运算.
	 * 由scale参数指定精度，以后的数字四舍五入.
	 * 
	 * @param v1 被除数

	 * @param v2 除数
	 * @param scale 表示表示需要精确到小数点以后几位

	 */
	public static double divide(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}

		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	/**
	 * 提供精确的小数位四舍五入处理.
	 * 
	 * @param v 需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(v);
		return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
    public static int toInt(String str) {
		return org.apache.commons.lang.math.NumberUtils.toInt(str);
	}

	public static int toInt(String str, int defaultValue) {
		return org.apache.commons.lang.math.NumberUtils.toInt(str, defaultValue);
	}

	public static long toLong(String str) {
		return org.apache.commons.lang.math.NumberUtils.toLong(str);
	}

	public static long toLong(String str, long defaultValue) {
		return org.apache.commons.lang.math.NumberUtils.toLong(str, defaultValue);
	}

	public static float toFloat(String str) {
		return org.apache.commons.lang.math.NumberUtils.toFloat(str);
	}

	public static float toFloat(String str, float defaultValue) {
		return org.apache.commons.lang.math.NumberUtils.toFloat(str, defaultValue);
	}

	public static double toDouble(String str) {
		return org.apache.commons.lang.math.NumberUtils.toDouble(str);
	}

	public static double toDouble(String str, double defaultValue) {
		return org.apache.commons.lang.math.NumberUtils.toDouble(str, defaultValue);
	}

	public static Number createNumber(String str) throws NumberFormatException {
		return org.apache.commons.lang.math.NumberUtils.createNumber(str);
	}

	public static Float createFloat(String str) {
		return org.apache.commons.lang.math.NumberUtils.createFloat(str);
	}

	public static Double createDouble(String str) {
		return org.apache.commons.lang.math.NumberUtils.createDouble(str);
	}

	public static Integer createInteger(String str) {
		return org.apache.commons.lang.math.NumberUtils.createInteger(str);
	}

	public static Long createLong(String str) {
		return org.apache.commons.lang.math.NumberUtils.createLong(str);
	}

	public static BigInteger createBigInteger(String str) {
		return org.apache.commons.lang.math.NumberUtils.createBigInteger(str);
	}

	public static BigDecimal createBigDecimal(String str) {
		return org.apache.commons.lang.math.NumberUtils.createBigDecimal(str);
	}

	public static long min(long[] array) {
		return org.apache.commons.lang.math.NumberUtils.min(array);
	}

	public static int min(int[] array) {
		return org.apache.commons.lang.math.NumberUtils.min(array);
	}

	public static short min(short[] array) {
		return org.apache.commons.lang.math.NumberUtils.min(array);
	}

	public static double min(double[] array) {
		return org.apache.commons.lang.math.NumberUtils.min(array);
	}

	public static float min(float[] array) {
		return org.apache.commons.lang.math.NumberUtils.min(array);
	}

	public static long max(long[] array) {
		return org.apache.commons.lang.math.NumberUtils.max(array);
	}

	public static int max(int[] array) {
		return org.apache.commons.lang.math.NumberUtils.max(array);
	}

	public static short max(short[] array) {
		return org.apache.commons.lang.math.NumberUtils.max(array);
	}

	public static double max(double[] array) {
		return org.apache.commons.lang.math.NumberUtils.max(array);
	}

	public static float max(float[] array) {
		return org.apache.commons.lang.math.NumberUtils.max(array);
	}

	public static long min(long a, long b, long c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static int min(int a, int b, int c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static short min(short a, short b, short c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static byte min(byte a, byte b, byte c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static double min(double a, double b, double c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static float min(float a, float b, float c) {
		return org.apache.commons.lang.math.NumberUtils.min(a, b, c);
	}

	public static long max(long a, long b, long c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static int max(int a, int b, int c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static short max(short a, short b, short c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static byte max(byte a, byte b, byte c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static double max(double a, double b, double c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static float max(float a, float b, float c) {
		return org.apache.commons.lang.math.NumberUtils.max(a, b, c);
	}

	public static int compare(double lhs, double rhs) {
		return org.apache.commons.lang.math.NumberUtils.compare(lhs, rhs);
	}

	public static int compare(float lhs, float rhs) {
		return org.apache.commons.lang.math.NumberUtils.compare(lhs, rhs);
	}

	public static boolean isDigits(String str) {
		return org.apache.commons.lang.math.NumberUtils.isDigits(str);
	}

	public static boolean isNumber(String str) {
		return org.apache.commons.lang.math.NumberUtils.isNumber(str);
	}
}
